using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 对象池管理器 - 统一管理所有对象池
/// </summary>
public class PoolManager : MonoBehaviour
{
    public static PoolManager Instance { get; private set; }
    
    private Dictionary<System.Type, object> m_Pools = new Dictionary<System.Type, object>();
    private Dictionary<string, object> m_NamedPools = new Dictionary<string, object>();
    
    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }
    
    /// <summary>
    /// 注册对象池
    /// </summary>
    public void RegisterPool<T>(IPool<T> pool) where T : class
    {
        m_Pools[typeof(T)] = pool;
        Logger.Log("PoolManager", $"Pool registered for type: {typeof(T).Name}");
    }
    
    /// <summary>
    /// 注册命名对象池
    /// </summary>
    public void RegisterNamedPool<T>(string name, IPool<T> pool) where T : class
    {
        m_NamedPools[name] = pool;
        Logger.Log("PoolManager", $"Named pool registered: {name} for type: {typeof(T).Name}");
    }
    
    /// <summary>
    /// 获取对象池
    /// </summary>
    public IPool<T> GetPool<T>() where T : class
    {
        if (m_Pools.TryGetValue(typeof(T), out var pool))
        {
            return pool as IPool<T>;
        }
        Logger.LogError("PoolManager", $"Pool not found for type: {typeof(T).Name}");
        return null;
    }
    
    /// <summary>
    /// 获取命名对象池
    /// </summary>
    public IPool<T> GetNamedPool<T>(string name) where T : class
    {
        if (m_NamedPools.TryGetValue(name, out var pool))
        {
            return pool as IPool<T>;
        }
        Logger.LogError("PoolManager", $"Named pool not found: {name}");
        return null;
    }
    
    /// <summary>
    /// 创建GameObject对象池
    /// </summary>
    public IPool<GameObject> CreateGameObjectPool(GameObject prefab, int initialSize = 10, int maxSize = 100, Transform parent = null)
    {
        var factory = new GameObjectPoolFactory(prefab, parent);
        var pool = new GameObjectPool(factory, initialSize, maxSize);
        RegisterPool(pool);
        return pool;
    }
    
    /// <summary>
    /// 创建MonoBehaviour对象池
    /// </summary>
    public IPool<T> CreateMonoBehaviourPool<T>(T prefab, int initialSize = 10, int maxSize = 100, Transform parent = null) where T : MonoBehaviour
    {
        var factory = new MonoBehaviourPoolFactory<T>(prefab, parent);
        var pool = new MonoBehaviourPool<T>(factory, initialSize, maxSize);
        RegisterPool(pool);
        return pool;
    }
    
    /// <summary>
    /// 创建普通对象池
    /// </summary>
    public IPool<T> CreateObjectPool<T>(int initialSize = 10, int maxSize = 100) where T : class, new()
    {
        var factory = new ObjectPoolFactory<T>();
        var pool = new ObjectPool<T>(factory, initialSize, maxSize);
        RegisterPool(pool);
        return pool;
    }
    
    /// <summary>
    /// 清理所有对象池
    /// </summary>
    public void ClearAllPools()
    {
        foreach (var pool in m_Pools.Values)
        {
            if (pool is IPool<object> objectPool)
            {
                objectPool.Clear();
            }
        }
        
        foreach (var pool in m_NamedPools.Values)
        {
            if (pool is IPool<object> objectPool)
            {
                objectPool.Clear();
            }
        }
        
        m_Pools.Clear();
        m_NamedPools.Clear();
        Logger.Log("PoolManager", "All pools cleared");
    }
    
    private void OnDestroy()
    {
        ClearAllPools();
    }
}
